package com.byt.framlib.commonwidget.finder.addresswheelfinder.picker;

import android.app.Activity;
import androidx.annotation.NonNull;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;

import com.byt.framlib.commonutils.LunarCalendarUtils;
import com.byt.framlib.commonutils.TimeUtil;
import com.byt.framlib.commonwidget.finder.addresswheelfinder.widget.WheelView;

import java.util.ArrayList;
import java.util.Calendar;

/**
 * 日期时间选择器，可同时选中日期及时间，另见{@link DatePicker}和{@link TimePicker}
 */
public class CanlenderPicker extends WheelPicker {

    private ArrayList<String> yearsLunar = new ArrayList<>();
    private ArrayList<String> monthsLunar = new ArrayList<>();
    private ArrayList<String> daysLunar = new ArrayList<>();

    private int selectedYearIndex = 0, selectedMonthIndex = 0, selectedDayIndex = 0;
    private OnWheelListener onWheelListener;
    private OnYearMonthDayTimePickListener onDateTimePickListener;
    private int startYear = 1901, startMonth = 1, startDay = 1;
    private int endYear = 2090, endMonth = 12, endDay = 31;
    private boolean resetWhileWheel = true;

    public CanlenderPicker(Activity activity) {
        super(activity);
        if (selectedMonthIndex < 720) {
            textSize = 14;//年月日时分，比较宽，设置字体小一点才能显示完整
        } else if (screenWidthPixels < 480) {
            textSize = 12;
        }
        initYearData();
    }

    /**
     * 滚动时是否重置下一级的索引
     */
    public void setResetWhileWheel(boolean resetWhileWheel) {
        this.resetWhileWheel = resetWhileWheel;
    }

    /**
     * 设置年份范围
     *
     * @deprecated use
     */
    @Deprecated
    public void setRange(int startYear, int endYear) {
        this.startYear = startYear;
        this.endYear = endYear;
        initYearData();
    }

    /**
     * 设置范围：开始的年月日
     */
    public void setDateRangeStart(int startYear, int startMonth, int startDay) {
        LunarCalendarUtils.Lunar lunar = LunarCalendarUtils.solarToLunar(new LunarCalendarUtils.Solar(startYear, startMonth, startDay));
        this.startYear = lunar.lunarYear;
        this.startMonth = lunar.lunarMonth;
        this.startDay = lunar.lunarDay;
        initYearData();
    }

    /**
     * 设置范围：结束的年月日
     */
    public void setDateRangeEnd(int endYear, int endMonth, int endDay) {
        LunarCalendarUtils.Lunar lunar = LunarCalendarUtils.solarToLunar(new LunarCalendarUtils.Solar(endYear, endMonth, endDay));
        this.endYear = lunar.lunarYear;
        this.endMonth = lunar.lunarMonth;
        this.endDay = lunar.lunarDay;
        initYearData();
    }

    /**
     * 设置默认选中的年月日时分
     */
    public void setSelectedItem(int year, int month, int day) {
        initYearData();
        LunarCalendarUtils.Lunar lunar = LunarCalendarUtils.solarToLunar(new LunarCalendarUtils.Solar(year, month, day));
        changeMonthData(lunar.lunarYear);
        selectedYearIndex = yearsLunar.indexOf(lunar.lunarYear + "年");
        if (LunarCalendarUtils.leapMonth(lunar.lunarYear) > 0) {
            selectedMonthIndex = monthsLunar.indexOf("闰" + LunarCalendarUtils.CHINESE_MONTH[lunar.lunarMonth - 1]);
        } else {
            selectedMonthIndex = monthsLunar.indexOf(LunarCalendarUtils.CHINESE_MONTH[lunar.lunarMonth - 1]);
        }
        changeDayData(lunar.lunarYear, selectedMonthIndex + 1);
        selectedDayIndex = daysLunar.indexOf(LunarCalendarUtils.getLunarDayStr(lunar.lunarDay));
    }

    public void setOnWheelListener(OnWheelListener onWheelListener) {
        this.onWheelListener = onWheelListener;
    }

    public void setOnDateTimePickListener(OnYearMonthDayTimePickListener listener) {
        this.onDateTimePickListener = listener;
    }

    public String getSelectedYearLunar() {
        if (yearsLunar.size() <= selectedYearIndex) {
            selectedYearIndex = yearsLunar.size() - 1;
        }
        return yearsLunar.get(selectedYearIndex);
    }

    public String getSelectedMonthLunar() {
        if (monthsLunar.size() <= selectedMonthIndex) {
            selectedMonthIndex = monthsLunar.size() - 1;
        }
        return monthsLunar.get(selectedMonthIndex);
    }

    public String getSelectedDayLunar() {
        if (daysLunar.size() <= selectedDayIndex) {
            selectedDayIndex = daysLunar.size() - 1;
        }
        return daysLunar.get(selectedDayIndex);
    }

    @NonNull
    @Override
    protected View makeCenterView() {
        // 如果未设置默认项，则需要在此初始化数据
        if (yearsLunar.size() == 0) {
            initYearData();
        }
        if (monthsLunar.size() == 0) {
            int selectedYear = TimeUtil.trimZero(getSelectedYearLunar().split("年")[0]);
            changeMonthData(selectedYear);
        }
        if (daysLunar.size() == 0) {
            Log.e("DateTimePicker", "init days before make view");
            int selectedYear = TimeUtil.trimZero(getSelectedYearLunar().split("年")[0]);
            changeDayData(selectedYear, selectedMonthIndex + 1);
        }
        LinearLayout layout = new LinearLayout(activity);
        layout.setOrientation(LinearLayout.HORIZONTAL);
        layout.setGravity(Gravity.CENTER);

        final WheelView yearView = createWheelView();
        final WheelView monthView = createWheelView();
        final WheelView dayView = createWheelView();

        yearView.setLayoutParams(new LinearLayout.LayoutParams(0, WRAP_CONTENT, 1.0f));
        yearView.setItems(yearsLunar, selectedYearIndex);
        yearView.setOnItemSelectListener(new WheelView.OnItemSelectListener() {
            @Override
            public void onSelected(int index) {
                selectedYearIndex = index;
                String selectedYearStr = yearsLunar.get(selectedYearIndex).split("年")[0];
                if (onWheelListener != null) {
                    onWheelListener.onYearWheeled(selectedYearIndex, selectedYearStr);
                }
                Log.e("DateTimePicker", "change months after year wheeled");
                if (resetWhileWheel) {
//                    selectedMonthIndex = 0;//重置月份索引
//                    selectedDayIndex = 0;//重置日子索引
                }
                //需要根据年份及月份动态计算天数
                int selectedYear = Integer.parseInt(selectedYearStr);
                String selectMonth = monthsLunar.get(selectedMonthIndex);
                String selectDay = daysLunar.get(selectedDayIndex);
                changeMonthData(selectedYear);
                if (resetWhileWheel) {
                    if (monthsLunar.contains(selectMonth)) {
                        selectedMonthIndex = monthsLunar.indexOf(selectMonth);
                    } else {
                        if (monthsLunar.size() > 0 && selectedMonthIndex >= monthsLunar.size()) {
                            selectedMonthIndex = monthsLunar.size() - 1;
                        } else {
                            selectedMonthIndex = 0;
                        }
                    }
                }
                monthView.setItems(monthsLunar, selectedMonthIndex);
                if (onWheelListener != null) {
                    onWheelListener.onMonthWheeled(selectedMonthIndex, monthsLunar.get(selectedMonthIndex));
                }
                changeDayData(selectedYear,selectedMonthIndex + 1);
                if (resetWhileWheel) {
                    if (daysLunar.contains(selectDay)) {
                        selectedDayIndex = daysLunar.indexOf(selectDay);
                    } else {
                        if (daysLunar.size() > 0 && selectedDayIndex >= daysLunar.size()) {
                            selectedDayIndex = daysLunar.size() - 1;
                        } else {
                            selectedDayIndex = 0;
                        }
                    }
                }
                dayView.setItems(daysLunar, selectedDayIndex);
                if (onWheelListener != null) {
                    onWheelListener.onDayWheeled(selectedDayIndex, daysLunar.get(selectedDayIndex));
                }
            }
        });
        layout.addView(yearView);

        monthView.setLayoutParams(new LinearLayout.LayoutParams(0, WRAP_CONTENT, 1.0f));
        monthView.setItems(monthsLunar, selectedMonthIndex);
        monthView.setOnItemSelectListener(new WheelView.OnItemSelectListener() {
            @Override
            public void onSelected(int index) {
                selectedMonthIndex = index;
                String selectedMonthStr = monthsLunar.get(selectedMonthIndex);
                if (onWheelListener != null) {
                    onWheelListener.onMonthWheeled(selectedMonthIndex, selectedMonthStr);
                }
                if (resetWhileWheel) {
//                    selectedDayIndex = 0;//重置日子索引
                }
                String selectDay = daysLunar.get(selectedDayIndex);
                int selectedYear;
                selectedYear = TimeUtil.trimZero(getSelectedYearLunar().split("年")[0]);
                changeDayData(selectedYear, selectedMonthIndex + 1);
                if (resetWhileWheel) {
                    if (daysLunar.contains(selectDay)) {
                        selectedDayIndex = daysLunar.indexOf(selectDay);
                    } else {
                        if (daysLunar.size() > 0 && selectedDayIndex >= daysLunar.size()) {
                            selectedDayIndex = daysLunar.size() - 1;
                        } else {
                            selectedDayIndex = 0;
                        }
                    }
                }
                dayView.setItems(daysLunar, selectedDayIndex);
                if (onWheelListener != null) {
                    onWheelListener.onDayWheeled(selectedDayIndex, daysLunar.get(selectedDayIndex));
                }
            }
        });
        layout.addView(monthView);

        dayView.setLayoutParams(new LinearLayout.LayoutParams(0, WRAP_CONTENT, 1.0f));
        dayView.setItems(daysLunar, selectedDayIndex);
        dayView.setOnItemSelectListener(new WheelView.OnItemSelectListener() {
            @Override
            public void onSelected(int index) {
                selectedDayIndex = index;
                if (onWheelListener != null) {
                    onWheelListener.onDayWheeled(selectedDayIndex, daysLunar.get(selectedDayIndex));
                }
            }
        });
        layout.addView(dayView);
        return layout;
    }

    @Override
    protected void onSubmit() {
        if (onDateTimePickListener == null) {
            return;
        }
        String date = getSelectedYearLunar() + " " + getSelectedMonthLunar() + " " + getSelectedDayLunar();
        int year = Integer.parseInt(getSelectedYearLunar().split("年")[0]);
        int day = selectedDayIndex + 1;
        int month = selectedMonthIndex + 1;
        boolean isLeapMonth = false;
        if (LunarCalendarUtils.leapMonth(year) > 0) {
            isLeapMonth = true;
            if (selectedMonthIndex >= LunarCalendarUtils.leapMonth(year)) {
                month = selectedMonthIndex;
            } else {
                month = selectedMonthIndex + 1;
            }
        }
        (onDateTimePickListener).onDateTimePicked(date, year, month, day, isLeapMonth);
    }

    private void initYearData() {
        yearsLunar.clear();
        if (startYear == endYear) {
            yearsLunar.add(String.valueOf(startYear) + "年");
        } else if (startYear < endYear) {
            //年份正序
            for (int i = startYear; i <= endYear; i++) {
                yearsLunar.add(String.valueOf(i) + "年");
            }
        } else {
            //年份逆序
            for (int i = startYear; i >= endYear; i--) {
                yearsLunar.add(String.valueOf(i) + "年");
            }
        }

        if (!resetWhileWheel) {
            int index = yearsLunar.indexOf(Calendar.getInstance().get(Calendar.YEAR));
            if (index == -1) {
                //当前设置的年份不在指定范围，则默认选中范围开始的年
                selectedYearIndex = 0;
            } else {
                selectedYearIndex = index;
            }
        }
    }

    private void changeMonthData(int selectedYear) {
        String preSelectMonth = "";
        if (!resetWhileWheel) {
            if (monthsLunar.size() > selectedMonthIndex) {
                preSelectMonth = monthsLunar.get(selectedMonthIndex);
            } else {
                preSelectMonth = TimeUtil.fillZero(Calendar.getInstance().get(Calendar.MONTH) + 1);
            }
        }
        monthsLunar.clear();
        int lunarMonth = LunarCalendarUtils.leapMonth(selectedYear);
        if (startYear == endYear) {
            if (startMonth > endMonth) {
                for (int i = endMonth; i >= startMonth; i--) {
                    monthsLunar.add(LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                    if (lunarMonth > 0 && lunarMonth == i) {
                        monthsLunar.add("闰" + LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                    }
                }
            } else {
                for (int i = startMonth; i <= endMonth; i++) {
                    monthsLunar.add(LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                    if (lunarMonth > 0 && lunarMonth == i) {
                        monthsLunar.add("闰" + LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                    }
                }
            }
        } else if (selectedYear == startYear) {
            for (int i = startMonth; i <= 12; i++) {
                monthsLunar.add(LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                if (lunarMonth > 0 && lunarMonth == i) {
                    monthsLunar.add("闰" + LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                }
            }
        } else if (selectedYear == endYear) {
            for (int i = 1; i <= endMonth; i++) {
                monthsLunar.add(LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                if (lunarMonth > 0 && lunarMonth == i) {
                    monthsLunar.add("闰" + LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                }
            }
        } else {
            for (int i = 1; i <= 12; i++) {
                monthsLunar.add(LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                if (lunarMonth > 0 && lunarMonth == i) {
                    monthsLunar.add("闰" + LunarCalendarUtils.CHINESE_MONTH[i - 1]);
                }
            }
        }
        if (!resetWhileWheel) {
            //当前设置的月份不在指定范围，则默认选中范围开始的月份
            int preSelectMonthIndex = monthsLunar.indexOf(preSelectMonth);
            selectedMonthIndex = preSelectMonthIndex == -1 ? 0 : preSelectMonthIndex;
        }
    }

    private void changeDayData(int selectedYear, int selectedMonth) {
        int month = LunarCalendarUtils.leapMonth(selectedYear);
        int maxLunarDays = 30;
        if (month > 0) {
            if (selectedMonth - 1 < month) {
                maxLunarDays =  LunarCalendarUtils.daysInMonth(selectedYear, selectedMonth);
            } else if ((selectedMonth - 1) ==  month){
                maxLunarDays =  LunarCalendarUtils.daysInMonth(selectedYear, month,true);
            } else {
                maxLunarDays =  LunarCalendarUtils.daysInMonth(selectedYear, selectedMonth - 1);
            }
        } else {
            maxLunarDays =  LunarCalendarUtils.daysInMonth(selectedYear, selectedMonth);
        }
        String preSelectDay = "";
        if (!resetWhileWheel) {
            if (selectedDayIndex >= maxLunarDays) {
                //如果之前选择的日是之前年月的最大日，则日自动为该年月的最大日
                selectedDayIndex = maxLunarDays - 1;
            }
            if (daysLunar.size() > selectedDayIndex) {
                //年或月变动时，保持之前选择的日不动
                preSelectDay = daysLunar.get(selectedDayIndex);
            } else {
                preSelectDay = TimeUtil.fillZero(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
            }
        }
        daysLunar.clear();
        if (selectedYear == startYear && selectedMonth == startMonth
                && selectedYear == endYear && selectedMonth == endMonth) {
            //开始年月及结束年月相同情况
            for (int i = startDay; i <= endDay; i++) {
                daysLunar.add(LunarCalendarUtils.getLunarDayStr(i));
            }
        } else if (selectedYear == startYear && selectedMonth == startMonth) {
            //开始年月相同情况
            for (int i = startDay; i <= maxLunarDays; i++) {
                daysLunar.add(LunarCalendarUtils.getLunarDayStr(i));
            }
        } else if (selectedYear == endYear && selectedMonth == endMonth) {
            //结束年月相同情况
            for (int i = 1; i <= endDay; i++) {
                daysLunar.add(LunarCalendarUtils.getLunarDayStr(i));
            }
        } else {
            for (int i = 1; i <= maxLunarDays; i++) {
                daysLunar.add(LunarCalendarUtils.getLunarDayStr(i));
            }
        }
        if (!resetWhileWheel) {
            //当前设置的日子不在指定范围，则默认选中范围开始的日子
            int preSelectDayIndex = daysLunar.indexOf(preSelectDay);
            selectedDayIndex = preSelectDayIndex == -1 ? 0 : preSelectDayIndex;
        }
    }

    public interface OnWheelListener {

        void onYearWheeled(int index, String year);

        void onMonthWheeled(int index, String month);

        void onDayWheeled(int index, String day);
    }

    public interface OnYearMonthDayTimePickListener {

        void onDateTimePicked(String date, int year, int month, int day, boolean isLeapMonth);

    }
}